package Infix2RPM.processor.infixElement;

import Infix2RPM.processor.Exception.BasicOperandException;
import Infix2RPM.processor.Exception.LogicException;
import Infix2RPM.processor.Stack.BasicOperand;

public class BooleanOperand implements BasicOperand {
	private Boolean value = null;

	public BooleanOperand(Boolean value) {
		this.value = value;
	}

	public BasicOperand add(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error,  '" + operand.getValue()
				+ "' seen next to " + this.value, this.className());
	}

	public BasicOperand subtract(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BasicOperand divide(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BasicOperand multiply(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BasicOperand power(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BasicOperand mod(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value, this
				.getClass().getName());
	}

	public BasicOperand concat(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BooleanOperand equal(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValueAsString() + "' seen next to " + this.value,
				this.className());
	}

	public BooleanOperand lessThan(BasicOperand operand) throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BooleanOperand lessThanEqual(BasicOperand operand)
			throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BooleanOperand greaterThan(BasicOperand operand)
			throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BooleanOperand greaterThanEqual(BasicOperand operand)
			throws LogicException {
		throw new BasicOperandException("Syntax error, extra operand '"
				+ operand.getValue() + "' seen next to " + this.value,
				this.className());
	}

	public BooleanOperand or(BasicOperand operand) throws LogicException {
		if (!(operand.getValue() instanceof Boolean)) {
			toss("operand is not a Boolean");
		}
		return new BooleanOperand(this.value || (Boolean) operand.getValue());
	}

	public BooleanOperand and(BasicOperand operand) throws LogicException {
		if (!(operand.getValue() instanceof Boolean)) {
			toss("operand is not a Boolean");
		}
		return new BooleanOperand(this.value && (Boolean) operand.getValue());
	}

	public boolean isNull() {
		return this.value == null;
	}

	public boolean isEmpty() {
		return this.value == null;
	}

	public Object getValue() {
		return this.value;
	}

	public String getValueAsString() {
		return this.value.toString();
	}

	private void toss(String message) throws LogicException {
		throw new BasicOperandException(message, this.getClass().getName());
	}
	
	public boolean isEqual(String token) {
		return this.value.toString().equals(token);
	}

	private String className() {
		return this.getClass().getName();
	}
}
